//////////////////////////////////////////////
// TargetOperations.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward declarations ---------------------

namespace nkGraphics
{
	class ClearTargetsPass ;
	class ComputePass ;
	class InstancingPass ;
	class MonoMaterialPass ;
	class Pass ;
	class PostProcessPass ;
	class RaytracingPass ;
	class RenderScenePass ;
	class System ;
	class Texture ;
	class Viewport ;
}

/// Includes ---------------------------------

// nkGraphics
#include "../Dll/DllDefines.h"

#include "TargetDescriptor.h"

// nkExport
#include <NilkinsExport/Exportable/Exportable.h>

// nkMemory
#include <NilkinsMemory/Containers/String.h>
#include <NilkinsMemory/Containers/StringView.h>

#include <NilkinsMemory/Pointers/UniquePtr.h>

// Standards
#include <utility>
#include <vector>

/// Class ------------------------------------

namespace nkGraphics
{	
	class DLL_GRAPHICS_EXPORT TargetOperations : public nkExport::Exportable
	{		
		public :
		
			// Constructor, destructor
			TargetOperations (System* system) noexcept ;
			TargetOperations (const TargetOperations&) = delete ;
			virtual ~TargetOperations () ;

			// Getters
			nkMemory::StringView getName () const ;

			// Setters
			void setName (nkMemory::StringView name) ;

			// Pass management
			virtual ClearTargetsPass* addClearTargetsPass (unsigned int index = -1) ;
			virtual ComputePass* addComputePass (unsigned int index = -1) ;
			virtual InstancingPass* addInstancingPass (unsigned int index = -1) ;
			virtual MonoMaterialPass* addMonoMaterialPass (unsigned int index = -1) ;
			virtual PostProcessPass* addPostProcessPass (unsigned int index = -1) ;
			virtual RaytracingPass* addRaytracingPass (unsigned int index = -1) ;
			virtual RenderScenePass* addRenderScenePass (unsigned int index = -1) ;
			// Pass getters
			unsigned int getPassCount () const ;
			Pass* getPass (unsigned int index) const ;
			// Manipulations
			virtual void deletePass (unsigned int index) ;
			virtual void changePassOrder (unsigned int fromIndex, unsigned int toIndex) ;

			// Concernant les targets
			virtual void setColorTarget (const TargetDescriptor& targetDesc, unsigned int outputIndex = 0) ;
			virtual void addColorTarget (const TargetDescriptor& targetDesc) ;
			virtual void changeColorTargetOrder (unsigned int fromIndex, unsigned int toIndex) ;
			virtual void removeColorTarget (unsigned int index) ;
			virtual void setDepthTarget (Texture* target) ;
			unsigned int getColorTargetCount () const ;
			Texture* getColorTarget (unsigned int index) const ;
			int getColorTargetRenderIndex (unsigned int index) const ;
			Texture* getDepthTarget () const ;
			virtual void setToBackBuffer (bool val, unsigned int indexInArray = 0) ;
			bool isToBackBuffer () const ;
			unsigned int getBackBufferViewIndex () const ;
			virtual void setToChainDepthBuffer (bool val) ;
			bool isToChainDepthBuffer () const ;

			// Viewport
			virtual void setOverloadedViewport (Viewport* value) ;
			Viewport* getOverloadedViewport () const ;

			// Execution
			virtual void execute () = 0 ;

			// Import / Export
			virtual void exportClassToTree (nkExport::Node* rootNode) override ;
			virtual void importClassFromTree (nkExport::Node* rootNode) override ;
			// Import / Export utilities
			void processColorTargetObjectNode (nkExport::Node* targetNode) ;
			void processPassObjectNode (nkExport::Node* passNode) ;

			// Operators
			TargetOperations& operator= (const TargetOperations&) = delete ;

		protected :
		
			// Attributs
			// Debug name
			nkMemory::String _name ;

			// Passes
			std::vector<nkMemory::UniquePtr<Pass>> _passList ;

			// Targets
			std::vector<TargetDescriptor> _colorTargets ;
			Texture* _depthTarget ;

			// Overload of viewport
			Viewport* _overloadedViewport ;
			Viewport* _tempViewport ;

			// Parent system
			System* _system ;

			// Target count
			unsigned int _targetsNumber ;

			// Back buffer info for a context
			unsigned int _backBufferViewIndex ;
			bool _toBackBuffer ;
			bool _toChainDepthBuffer ;
	} ;
}